package com.difsonapps.contacttranslator.ws.rest;

import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.difsonapps.contacttranslator.dto.ContactDTO;
import com.difsonapps.contacttranslator.dto.EmailDTO;
import com.difsonapps.contacttranslator.dto.EmailTypeEnum;
import com.difsonapps.contacttranslator.dto.NumberDTO;
import com.difsonapps.contacttranslator.dto.NumberTypeEnum;
import com.difsonapps.contacttranslator.dto.SocialContactDTO;
import com.difsonapps.contacttranslator.dto.SocialContactTypeEnum;
import com.difsonapps.contacttranslator.dto.TypeEnum;
import com.difsonapps.contacttranslator.dto.UserDTO;
import com.difsonapps.contacttranslator.service.itf.ContactService;
import com.difsonapps.contacttranslator.service.itf.EmailService;
import com.difsonapps.contacttranslator.service.itf.NumberService;
import com.difsonapps.contacttranslator.service.itf.SocialContactService;
import com.difsonapps.contacttranslator.service.itf.UserService;
import com.difsonapps.contacttranslator.utils.CommonProps;
import com.difsonapps.contacttranslator.utils.Utils;

@Controller
@RequestMapping(value = "/contact")
public class ContactCtrl {

	@Autowired
	UserService userService;
	
	ObjectMapper mapper;

	@Autowired
	EmailService emailService;

	@Autowired
	NumberService numberService;

	@Autowired
	SocialContactService socialContactService;

	@Autowired
	CommonProps commonProps;

	@Autowired
	ContactService contactService;

	@RequestMapping(value = "save", method = RequestMethod.POST)
	public @ResponseBody ContactDTO save(@RequestBody ContactDTO contactDTO){
		
		
		mapper = new ObjectMapper();
		
		List<NumberDTO> listOfNum = new ArrayList<NumberDTO>();
		for (NumberDTO numberDTO : contactDTO.getNumberDTOs()) {
			listOfNum.add(numberDTO);
		}
		List<EmailDTO> listOfEmail = new ArrayList<EmailDTO>();
		for (EmailDTO emailDTO : contactDTO.getEmailDTOs()) {
			listOfEmail.add(emailDTO);
		}
		List<SocialContactDTO> listOfso = new ArrayList<SocialContactDTO>();
		for (SocialContactDTO emailDTO : contactDTO.getSocialContactDTOs()) {
			listOfso.add(emailDTO);
		}
		
		UserDTO user = userService.getByEmail( contactDTO.getUser().getEmail());
		if(user == null )
			return null;
		List<ContactDTO>  listOfcontactDTO = contactService.getByNumberAndEmail(contactDTO.getContactId(), contactDTO.getDeviceId(), contactDTO.getUser().getEmail(), 
										getNumberInStringArray(contactDTO.getNumberDTOs()), 
										getEmailInStringArray(contactDTO.getEmailDTOs()));
		
		if(listOfcontactDTO != null && listOfcontactDTO.size() == 0){
			System.out.println("Nouveau - Ajouter");
			contactDTO.getNumberDTOs().clear();
			contactDTO.getEmailDTOs().clear();
			contactDTO.getSocialContactDTOs().clear();
			contactDTO.setUser(userService.getByEmail( contactDTO.getUser().getEmail()));
			contactService.insert(contactDTO);
			
			for (NumberDTO numberDTO : listOfNum) {
				numberDTO.setContactDTO(contactDTO);
			}
			for (EmailDTO emailDTO : listOfEmail) {
				emailDTO.setContactDTO(contactDTO);
			}
			for (SocialContactDTO emailDTO : listOfso) {
				emailDTO.setContactDTO(contactDTO);
			}
			contactDTO.setNumberDTOs(listOfNum);
			contactDTO.setEmailDTOs(listOfEmail);
			contactDTO.setSocialContactDTOs(listOfso);
			
			contactService.update(contactDTO);
			return contactDTO;
		}else{ //if(listOfcontactDTO != null && listOfcontactDTO.size() == 1){
			ContactDTO contactDTO2 = listOfcontactDTO.get(0);
			contactDTO2.setCompanyName(contactDTO.getCompanyName());
			contactDTO2.setContactId(contactDTO.getContactId());
			contactDTO2.setDeviceId(contactDTO.getDeviceId());
			contactDTO2.setDisplayName(contactDTO.getDisplayName());				
			
			mergeEmails(contactDTO2.getEmailDTOs(), contactDTO.getEmailDTOs());
			//contactDTO2.getEmailDTOs().addAll(contactDTO.getEmailDTOs());
			contactDTO2.setNickName(contactDTO.getNickName());			
			mergeNumber(contactDTO2.getNumberDTOs(), contactDTO.getNumberDTOs());
			//contactDTO2.getNumberDTOs().addAll(contactDTO.getNumberDTOs());
			contactDTO2.setPhoto(contactDTO.getPhoto());			
			mergeSocialContact(contactDTO2.getSocialContactDTOs(), contactDTO.getSocialContactDTOs());
			//contactDTO2.getSocialContactDTOs().addAll(contactDTO.getSocialContactDTOs());
			contactDTO2.setTitle(contactDTO.getTitle());
			contactService.update(contactDTO2);
			System.out.println("Nouveau - Modifier");
			return  contactDTO2;
			
		}/*else{
			
			System.out.println("Nouveau - Fusionner");
		}
		*/
	}
	
	private void mergeEmails(List<EmailDTO> list1, List<EmailDTO> list2){
		int i = 0;
		for (EmailDTO emailDTO : list1) {
			if(list2.contains(emailDTO))
				list2.remove(emailDTO);
			else
				list2.get(i++).setContactDTO(emailDTO.getContactDTO());
			
				
		}
		list1.addAll(list2);
	}
	private void mergeNumber(List<NumberDTO> list1, List<NumberDTO> list2){
		int i = 0;
		for (NumberDTO numberDTO : list1) {
			if(list2.contains(numberDTO))
				list2.remove(numberDTO);
			else 
				list2.get(i++).setContactDTO(numberDTO.getContactDTO());
			
		}
		list1.addAll(list2);
	}
	
	private void mergeSocialContact(List<SocialContactDTO> list1, List<SocialContactDTO> list2){
		int i = 0;
		for (SocialContactDTO socialContactDTO : list1) {
			if(list2.contains(socialContactDTO))
				list2.remove(socialContactDTO);
			else
				list2.get(i++).setContactDTO(socialContactDTO.getContactDTO());
			
		}
		list1.addAll(list2);
	}
	
	private String[]getEmailInStringArray( List<EmailDTO> listOfEmail){
		String[] result = new String[listOfEmail.size()];
		int i = 0;
		for (EmailDTO email : listOfEmail) {
			result[i++]  = email.getValue();
	 	}		
		return result;
	}
	

	private String[]getNumberInStringArray(List<NumberDTO> listOfNumber){
		String[] result = new String[listOfNumber.size()];
		int i = 0;
		for (NumberDTO number : listOfNumber) {
			result[i++]  = number.getValue();
	 	}		
		return result;
	}
	
	@RequestMapping(method = RequestMethod.POST, value = "add/email/{email}/contactid/{contactid}/deviceid/{deviceid}/displayname/{displayname}/nickname/{nickname}/companyname/{companyname}/title/{title}/type/{type}/emails/{emails}/numbers/{numbers}/socialcontacts/{socialcontacts}")
	public @ResponseBody
	ContactDTO addsc(@PathVariable String email,
			@PathVariable String contactid, @PathVariable String deviceid,
			@PathVariable String displayname, @PathVariable String nickname,
			@PathVariable String companyname, @PathVariable String title,
			@PathVariable int type, @PathVariable String emails,
			@PathVariable String numbers, @PathVariable String socialcontacts) {

		List<EmailDTO> listEmailDTO = null;
		List<NumberDTO> listNumberDTO = null;
		List<SocialContactDTO> listSocialContactDTO = null;

		UserDTO user = userService.getByEmail(email);
		if (user == null) {
			return null;
		}

		ContactDTO contactDTO = contactService.getByContactIdDeviceId(
				contactid, deviceid);
		if (contactDTO == null) {
			contactDTO = new ContactDTO();
		}
		if (contactDTO != null) {
			
			
			listEmailDTO = contactDTO.getEmailDTOs();
			listNumberDTO = contactDTO.getNumberDTOs();
			listSocialContactDTO = contactDTO.getSocialContactDTOs();
		}

		if (listEmailDTO == null) {
			listEmailDTO = new ArrayList<EmailDTO>();
		}
		if (listNumberDTO == null) {
			listNumberDTO = new ArrayList<NumberDTO>();
		}
		if (listSocialContactDTO == null) {
			listSocialContactDTO = new ArrayList<SocialContactDTO>();
		}

		contactDTO.setCompanyName(companyname);
		contactDTO.setContactId(contactid);
		contactDTO.setDeviceId(deviceid);
		contactDTO.setDisplayName(displayname);
		contactDTO.setNickName(nickname);
		contactDTO.setTitle(title);
		contactDTO.setType(TypeEnum.get(type));
		contactDTO.setUser(user);

		List<String> listMail = Utils
				.splitToList(emails, commonProps.separator);

		if (listMail != null && listMail.size() > 0) {
			for (String mail : listMail) {
				List<String> listMailType = Utils.splitToList(mail,
						commonProps.separatorType);
				if (listMailType != null && listMailType.size() > 1) {
					EmailDTO emailDTO = new EmailDTO(listMailType.get(0),
							EmailTypeEnum.get(Integer.valueOf(listMailType
									.get(1))));
					emailDTO.setContactDTO(contactDTO);
					if (!listEmailDTO.contains(emailDTO)) {
						listEmailDTO.add(emailDTO);
					}
				}

			}
		}

		List<String> listNumber = Utils.splitToList(numbers,
				commonProps.separator);

		if (listNumber != null && listNumber.size() > 0) {
			for (String number : listNumber) {
				List<String> listNumberType = Utils.splitToList(number,
						commonProps.separatorType);
				if (listNumberType != null && listNumberType.size() > 1) {
					NumberDTO numberDTO = new NumberDTO(listNumberType.get(0),
							NumberTypeEnum.get(Integer.valueOf(listNumberType
									.get(1))));
					numberDTO.setContactDTO(contactDTO);
					if (!listNumberDTO.contains(numberDTO)) {
						listNumberDTO.add(numberDTO);
					}
				}

			}
		}

		List<String> listSocialContact = Utils.splitToList(socialcontacts,
				commonProps.separator);

		if (listSocialContact != null && listSocialContact.size() > 0) {
			for (String socialContact : listSocialContact) {
				List<String> listSocialContactType = Utils.splitToList(
						socialContact, commonProps.separatorType);
				if (listSocialContactType != null
						&& listSocialContactType.size() > 1) {
					SocialContactDTO socialContactDTO = new SocialContactDTO(
							listSocialContactType.get(0),
							SocialContactTypeEnum.get(Integer
									.valueOf(listSocialContactType.get(1))));
					socialContactDTO.setContactDTO(contactDTO);
					if (!listSocialContactDTO.contains(contactDTO)) {
						listSocialContactDTO.add(socialContactDTO);
					}
				}

			}
		}
		System.out.println("listEmailDTO "+listEmailDTO);
		System.out.println("listNumberDTO "+listNumberDTO);
		System.out.println("listSocialContactDTO "+listSocialContactDTO);
		contactDTO.setEmailDTOs(listEmailDTO);
		contactDTO.setNumberDTOs(listNumberDTO);
		contactDTO.setSocialContactDTOs(listSocialContactDTO);
		if(contactDTO.getId() == 0)
			contactService.insert(contactDTO);
		else
			contactService.update(contactDTO);
		
		//contactDTO.setNumberDTOs(listNumberDTO);
		//contactDTO.setSocialContactDTOs(listSocialContactDTO);

		
		System.out.println(contactDTO);
		return contactDTO;
	}

	@RequestMapping(method = RequestMethod.GET, value = "contacts/email/{email}/")
	public @ResponseBody
	List<ContactDTO> contacts(@PathVariable String email) {
		
		if (email != null) {
		//	email.replace(";", ".");
			List<ContactDTO> contactDTOs = contactService.getByUserEmail(email);
			return contactDTOs;
		}
		return null;
	}

}
